﻿using System;
using System.Collections.Generic; 
using System.Text;
using System.Threading;

namespace DevelopAssistant.Core
{
    public delegate void ThreadHandler(object stateInfo);

    public class CountDownLatch
    {
        private object lockobj = new object();
        private int counts;

        public int Counts()
        {
            return this.counts;
        }

        public CountDownLatch(int counts)
        {
            this.counts = counts;
        }

        public void Await()
        {
            lock (lockobj)
            {
                while (counts > 0)
                {
                    Monitor.Wait(lockobj);
                }
            }
        }

        public void CountDown()
        {
            lock (lockobj)
            {
                counts--;
                Monitor.PulseAll(lockobj);
            }
        }
    }

    public class ThreadPoolHelper
    {
        public void ExecuteThreads(ThreadHandler[] handlers,ref string message)
        {
            try
            {
                CountDownLatch cdl = new CountDownLatch(handlers.Length);
                foreach (ThreadHandler handler in handlers)
                {
                    ThreadPool.QueueUserWorkItem(new WaitCallback(handler), cdl);
                }
                cdl.Await();
                message = "执行完成";
            }
            catch (Exception ex)
            {
                message = ex.Message;
            }           
        }

        #region ThreadPoolHelper Demo

        private void Thread_DoEvent(object stateInfo)
        {
            //do something

            CountDownLatch counterDownLatch = (CountDownLatch)stateInfo;
            counterDownLatch.CountDown();
        }

        private void ThreadPoolDemo()
        {
            string message = String.Empty;
            ThreadHandler[] tasks = new ThreadHandler[3];
            tasks[0] = new ThreadHandler(Thread_DoEvent);
            tasks[1] = new ThreadHandler(Thread_DoEvent);
            tasks[2] = new ThreadHandler(Thread_DoEvent);

            Thread th = new Thread(() =>
            {
                ExecuteThreads(tasks, ref message);
            });
            th.IsBackground = true;
            th.Start();
            
        }

        #endregion

    }
}
